﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using GoodMan.Infrastructure.Entities.Entity;
using GoodMan.Infrastructure.Entities;
using GoodMan.Infrastructure.Entities.Enum;
using GoodMan.Portal.Biz.Model;
using GoodMan.Tool.Framework;
using GoodMan.Portal.Biz.Content;
using GoodMan.Engine.ExServer.WorkPool;
using GoodMan.Engine.ExServer.WorkPool.WorkHandle.Email;
using GoodMan.Tool.Configration;
using System.Web.Security;
using GoodMan.Infrastructure.Entities.Cache;
using GoodMan.Infrastructure.Entities.Repository;
using System.Linq.Expressions;
using System.Data.SqlClient;
using System.Web;

namespace GoodMan.Portal.Biz
{
    public class UserBiz
    {
        //实例
        public static void Sample(int page, int pageSize)
        {
            using (Context ctx = new Context())
            {
                var o = ctx.ExcuteSQL("select * from t_user where username = @username",
                    new SqlParameter("@username","51944179@qq.com"));
            }
            var user = new User().Find("51944179@qq.com");
            var userList = new User().FindAll(c => c.IsActivate, c => c.UserName, page, pageSize);
            var isExist = new User().Any(c => c.UserName == "51944179@qq.com");
            var userCount = new User().Count(c => c.IsActivate);
            using (Context ctx = new Context())
            {
                var data = (from c in ctx.User
                            join di in ctx.Dormitory
                             on c.FloorId equals di.Id into dt
                            from d in dt.DefaultIfEmpty()
                            where c.IsActivate
                            group new { c, d } by c.UserName into g
                            orderby g.Key descending
                            select g)
                           .Skip(page * pageSize)
                           .Take(pageSize)
                           .ToList()
                           .Select(c => new User().Set(c.FirstOrDefault().c)
                               .LoadDormitories(c.Where(i => i.d != null).Select(i => new Dormitory().Set(i.d)).ToList()))
                           .ToList();
                var list = new ItemListBox<User>(data).BuildPage(
                    userCount, page, pageSize, new PageParameter() { Style = "workspace" });
            }
        }

        #region Account
        /// <summary>
        /// 注册
        /// </summary>
        /// <param name="entity"></param>
        /// <param name="NoEmail">true:不发邮件</param>
        /// <returns>注册失败返回null</returns>
        public static User Register(User member, bool NoEmail = false)
        {
            if (member != null && !String.IsNullOrEmpty(member.UserName)
                    && UserNotExists(member.UserName))
            {
                var token = new AccountToken()
                {
                    ExpireDate = DateTime.Now.AddDays(7),
                    Token = Guid.NewGuid().ToString(),
                    UserName = member.UserName
                };
                member.Token = token.Token;
                member.Password = AesAlgorithm.Encrypt(member.Password);
                member = member.PostAdd();
                if (member != null)
                {
                    if (!NoEmail)
                    {
                        string toMember = EmailBuilder.BuildRegisterActivtionEmail(
                            member.UserName, BuildFixToken(token));
                        if (!String.IsNullOrEmpty(toMember))
                        {
                            WorkPool.Append<NormalNotifyEmail>(WorkType.email_for_normalnotify,
                            new NormalNotifyEmail()
                            {
                                Message = toMember,
                                Title = SiteResource.SiteName + "--账号激活邮件",
                                Recipient = member.UserName
                            });
                        }
                        //WorkPool.Append<AccountEmail>(WorkType.email_for_register, new AccountEmail()
                        //{
                        //    Recipient = member.UserName,
                        //    Token = BuildFixToken(token)
                        //});
                    }
                    return member;
                }
            }
            return null;
        }
        private static string BuildFixToken(AccountToken token)
        {
            string str = token.ToJson();
            return EncodeByBase64.Encode(str);
        }
        public static User CheckToken(string token)
        {
            if (String.IsNullOrEmpty(token))
            {
                return null;
            }
            token = EncodeByBase64.Decode(token);
            var accountToken = token.ToObject<AccountToken>();
            if (accountToken != null)
            {
                var user = new User().Find(accountToken.UserName);
                if (user != null)
                {
                    if (user.Token == accountToken.Token
                        && accountToken.ExpireDate > DateTime.Now)
                    {
                        user.Token = Guid.NewGuid().ToString();
                        user.PostModify();
                        return user;
                    }
                }
            }
            return null;
        }
        public static User Activation(string token)
        {
            var member = CheckToken(token);
            if (member != null)
            {
                member.IsActivate = true;
                if (member.PostModify() != null)
                {
                    return member;
                }
            }
            return null;
        }
        /// <summary>
        /// 登陆
        /// </summary>
        /// <param name="userName"></param>
        /// <param name="password"></param>
        /// <param name="rememberMe"></param>
        /// <returns>登陆失败返回null</returns>
        public static User Login(string userName, string password, bool rememberMe = false)
        {
            var user = new User().Find(userName);
            if (user != null && !user.IsRefuse)
            {
                if (user.Password == AesAlgorithm.Encrypt(password))
                {
                    if (!user.IsActivate)
                    {
                        return new User() { IsActivate = false };
                    }
                    if (user.SystemRole == UserRole.Staff)
                    {
                        SupportBiz.UpdateOnlineState(user.UserName, Core.OnlineState.在线);
                    }
                    FormsAuthentication.SetAuthCookie(userName, rememberMe);
                    return user;
                }
            }
            return null;
        }
        public static void LogOut()
        {
            if (HttpContext.Current.User.Identity.IsAuthenticated)
            {
                var user = new User().Find(HttpContext.Current.User.Identity.Name);
                if (user != null && user.SystemRole == UserRole.Staff)
                {
                    SupportBiz.SetOffline(user.UserName);
                }
            }
            System.Web.Security.FormsAuthentication.SignOut();
        }
        /// <summary>
        /// true:不存在 false:存在
        /// </summary>
        /// <param name="userName"></param>
        /// <returns></returns>
        public static bool UserNotExists(string userName)
        {
            if (!String.IsNullOrEmpty(userName))
            {
                using (Context ctx = new Context())
                {
                    return !ctx.User.Any(c => c.UserName == userName);
                }
            }
            return false;
        }
        /// <summary>
        /// 发重置密码邮件
        /// </summary>
        /// <param name="userName"></param>
        /// <returns></returns>
        public static bool ResendForgotPasswordMail(string userName)
        {
            var user = new User().Find(userName);
            if (user != null)
            {
                var token = new AccountToken()
                {
                    ExpireDate = DateTime.Now.AddDays(1),
                    Token = Guid.NewGuid().ToString(),
                    UserName = userName
                };
                user.Token = token.Token;
                if (user.PostModify() != null)
                {
                    string toMember = EmailBuilder.BuildResetPasswordEmail(
                        user.UserName, BuildFixToken(token));
                    if (!String.IsNullOrEmpty(toMember))
                    {
                        WorkPool.Append<NormalNotifyEmail>(WorkType.email_for_normalnotify,
                         new NormalNotifyEmail()
                         {
                             Message = toMember,
                             Title = SiteResource.SiteName + "--密码重置验证",
                             Recipient = user.UserName
                         });
                    }
                    //WorkPool.Append<AccountEmail>(WorkType.email_for_resetpassword, new AccountEmail()
                    //{
                    //    Recipient = user.UserName,
                    //    Token = BuildFixToken(token)
                    //});
                }
                return true;
            }
            return false;
        }
        public static User ChangePassword(string userName, string password)
        {
            if (!String.IsNullOrEmpty(userName) &&
                !String.IsNullOrEmpty(password))
            {
                var user = new User().Find(userName);
                if (user != null)
                {
                    user.Password = AesAlgorithm.Encrypt(password);
                    if (user.PostModify() != null)
                    {
                        new UserCache().RefreshItem(userName);
                        return user;
                    }
                }
            }
            return null;

        }
        /// <summary>
        /// 更改密码
        /// </summary>
        /// <param name="userName"></param>
        /// <param name="password"></param>
        /// <returns></returns>
        public static User ChangePassword(string userName, string oldpassword, string password)
        {
            if (!String.IsNullOrEmpty(userName) &&
                !String.IsNullOrEmpty(password))
            {
                var user = new User().Find(userName);
                if (user != null)
                {
                    if (user.Password != AesAlgorithm.Encrypt(oldpassword))
                    {
                        return null;
                    }
                    user.Password = AesAlgorithm.Encrypt(password);
                    if (user.PostModify() != null)
                    {
                        return user;
                    }
                }
            }
            return null;
        }
        public static User ReSendActiveMail(string username)
        {
            if (String.IsNullOrEmpty(username))
            {
                return null;
            }
            var user = new User().Find(username);
            if (user != null && !user.IsActivate)
            {
                var token = new AccountToken()
                {
                    ExpireDate = DateTime.Now.AddDays(7),
                    Token = Guid.NewGuid().ToString(),
                    UserName = user.UserName
                };
                user.Token = token.Token;
                user = user.PostModify();
                if (user != null)
                {
                    string toMember = EmailBuilder.BuildRegisterActivtionEmail(
                            user.UserName, BuildFixToken(token));
                    if (!String.IsNullOrEmpty(toMember))
                    {
                        WorkPool.Append<NormalNotifyEmail>(WorkType.email_for_normalnotify,
                        new NormalNotifyEmail()
                        {
                            Message = toMember,
                            Title = SiteResource.SiteName + "--账号激活邮件",
                            Recipient = user.UserName
                        });
                    }
                    //WorkPool.Append<AccountEmail>(WorkType.email_for_register, new AccountEmail()
                    //{
                    //    Recipient = user.UserName,
                    //    Token = BuildFixToken(token)
                    //});
                    return user;
                }
            }
            return null;
        }
        #endregion

        #region 后台用户管理
        /// <summary>
        /// 获取所有的用户信息
        /// </summary>
        /// <param name="where"></param>
        /// <param name="page"></param>
        /// <param name="takeSize"></param>
        /// <returns></returns>
        public static ItemListBox<User> GetAllUserByWhere(Expression<Func<T_User, bool>> where, int page, int takeSize)
        {
            var userList = new User().FindAll(where, c => c.CreateDate, page, takeSize);
            return new ItemListBox<User>(userList).BuildPage(
                    new User().Count(where), page, takeSize, new PageParameter() { Style = "workspace" }); 
            
        }

        /// <summary>
        /// 模糊查询相关
        /// </summary>
        /// <param name="page"></param>
        /// <param name="takeSize"></param>
        /// <param name="systemRole"></param>
        /// <param name="floorId"></param>
        /// <param name="gender"></param>
        /// <param name="college"></param>
        /// <param name="dormitory"></param>
        /// <param name="nike"></param>
        /// <param name="name"></param>
        /// <returns></returns>
        public static ItemListBox<User> GetAllUserByWhere(int page, int takeSize, int systemRole = -1, int floorId = -1, int gender = -1, int college=-1,string dormitory = "", string nike = "", string name = "")
        {
            using (Context ctx = new Context())
            {
                var query = from c in ctx.User
                            select c;
                /*from c in ctx.User
                            join d in ctx.Dormitory
                                on c.FloorId equals d.Id
                                orderby c.CreateDate descending
                            select new { c, d };*/
                
                if (systemRole == -1)//学校管理员
                {
                    query = query.Where(c => c.SystemRole == 12 || c.SystemRole == 1);
                }
                else if (systemRole == -3)//超级财务
                {
                    query = query.Where(c => c.SystemRole == 21 || c.SystemRole == 1);
                }
                else if (systemRole == -2)
                {
                    query = query.Where(c => c.SystemRole == 20 || c.SystemRole == 11);
                }
                else if (systemRole != -2)//排除超级管理员
                {
                    query = query.Where(c => c.SystemRole == systemRole);
                }

                if (floorId != -1)//楼层
                {
                    query = query.Where(c => c.FloorId == floorId);
                }

                if (gender != -1) //性别
                {
                    query = query.Where(c => c.Gender == (gender == 0 ? false : true));
                }
                if (college != -1) //学校
                {
                    query = query.Where(c => c.CollegeId == college);
                }
                if (!string.IsNullOrEmpty(dormitory))//宿舍号
                {
                    query = query.Where(c => c.Dormitory.Contains(dormitory));
                }
                if (!string.IsNullOrEmpty(nike))//昵称
                {
                    query = query.Where(c => c.NickName.Contains(nike));
                }
                if (!string.IsNullOrEmpty(name))//真实姓名
                {
                    query = query.Where(c => c.RealName.Contains(name));
                }
                var data = query.OrderByDescending(c => c.CreateDate).Skip(page * takeSize).Take(takeSize).ToList().Select(c => new User().Set(c)).ToList();
                var itemCount = query.Count();
                return new ItemListBox<User>(data).BuildPage(itemCount, page, takeSize, new PageParameter()
                {
                    Style = "workspace"
                });
            }           
        }

        
        #endregion
    }
}
